﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.CodeDom.Compiler;
using System.Reflection;
using System.ComponentModel;
using System.Diagnostics;

namespace CodeScrapWindow
{
	internal static class CompilerFactory
	{
		private static readonly Dictionary<string, ICompilerProvider> _supportedCompilers;

		/// <summary>
		/// Gets the names of supported compilers.
		/// </summary>
		/// <value>The names of supported compilers.</value>
		public static string[] SupportedCompilers
		{
			get
			{
				string[] result = _supportedCompilers.Keys.ToArray();
				Array.Sort(result);
				return result;
			}
		}

		/// <summary>
		/// Initializes the <see cref="CompilerFactory"/> class.
		/// </summary>
		static CompilerFactory()
		{
			_supportedCompilers = new Dictionary<string, ICompilerProvider>();

			// Get all types in this assembly that implement ICompilerProvider and add them to our dictionary
			foreach (Type t in Assembly.GetCallingAssembly().GetTypes())
			{
				Type t2 = t.GetInterface(typeof(ICompilerProvider).FullName);
				if (t2 != null)
				{
					try
					{
						ICompilerProvider provider = (ICompilerProvider)Activator.CreateInstance(t);
						_supportedCompilers.Add(provider.Name, provider);
					}
					catch (Exception ex)
					{
						Trace.WriteLine("CompilerFactory:  " + ex.Message);
					}
				}
			}
		}

		/// <summary>
		/// Gets the compiler provider.
		/// </summary>
		/// <param name="compilerName">Name of the compiler.</param>
		/// <returns></returns>
		public static ICompilerProvider GetCompilerProvider(string compilerName)
		{
			if (!_supportedCompilers.ContainsKey(compilerName))
			{
				throw new ArgumentException(string.Format("{0} is not a supported compiler", compilerName));
			}

			return _supportedCompilers[compilerName];
		}
	}
}
